package com.wander.designCreational.proxyAndDecorate;;

import com.wander.designCreational.proxyAndDecorate.BitterCoffee;
import com.wander.designCreational.proxyAndDecorate.Coffee;

/**
 * @Author : WDYin
 * @Date : 2019/12/10
 * @Description : 测试类
 * 装饰器模式关注于在一个对象上动态地添加方法，而代理模式关注于控制对对象的访问。
 * 换句话说，用代理模式，代理类可以对它的客户隐藏一个对象的具体信息。
 * 因此当使用代理模式的时候，我们常常在一个代理类中创建一个对象的实例；
 * 当使用装饰器模式的时候，我们通常的做法是将原始对象作为一个参数传给装饰器的构造器。
 * 装饰器模式和代理模式的使用场景不一样，比如IO流使用的是装饰者模式，可以层层增加功能。而代理模式则一般是用于增加特殊的功能，有些动态代理不支持多层嵌套。
 * <p>
 * 代理和装饰其实从另一个角度更容易去理解两个模式的区别：代理更多的是强调对对象的访问控制，
 * 比如说，访问A对象的查询功能时，访问B对象的更新功能时，访问C对象的删除功能时，都需要判断对象是否登陆，
 * 那么我需要将判断用户是否登陆的功能抽提出来，并对A对象、B对象和C对象进行代理，使访问它们时都需要去判断用户是否登陆，
 * 简单地说就是将某个控制访问权限应用到多个对象上；而装饰器更多的强调给对象加强功能，比如说要给只会唱歌的A对象添加跳舞功能，
 * 添加说唱功能等，简单地说就是将多个功能附加在一个对象上。
 * <p>
 * 所以，代理模式注重的是对对象的某一功能的流程把控和辅助，它可以控制对象做某些事，重
 * 心是为了借用对象的功能完成某一流程，而非对象功能如何。而装饰模式注重的是对对象功能的扩展，
 * 不关心外界如何调用，只注重对对象功能加强，装饰后还是对象本身。
 * <p>
 * 总结
 * <p>
 * 对于代理类，如何调用对象的某一功能是思考重点，而不需要兼顾对象的所有功能；
 * 对于装饰类，如何扩展对象的某一功能是思考重点，同时也需要兼顾对象的其他功能，
 * 因为再怎么装饰，本质也是对象本身，要担负起对象应有的职责，被装饰者的职责一旦增加，
 * 作为装饰类也需要有相应的扩展，必然会造成编码的负担。
 * <p>
 * 设计模式本身是为了提升代码的可扩展性，灵活应用即可，不必生搬硬套，非要分出个所以然来，
 * 装饰器模式和代理模式的区别也是如此。
 */
public class OrderCoffer {
    public static void main(String[] args) {
        /** 默认点咖啡的逻辑 */
        Coffee coffee = new BitterCoffee();
        coffee.printlnMaterial();
    }
}
